/*
 * @Author: C.
 * @Date: 2025-04-15 16:26:12
 */
import { promises as fs } from 'node:fs';
import { dirname } from 'node:path';

/**
 * 将指定的数据以 JSON 格式写入到指定文件中。
 * 如果文件所在的目录不存在，会递归创建这些目录。
 *
 * @param filePath - 要写入的文件的路径。
 * @param data - 要写入文件的数据，可以是任何可以被序列化为 JSON 的数据类型。
 * @param spaces - 用于格式化 JSON 字符串的缩进空格数，默认为 2。
 * @throws 当创建目录或写入文件时发生错误，会抛出错误并在控制台输出错误信息。
 */
export async function outputJSON(
  // 要写入的文件的路径
  filePath: string,
  // 要写入文件的数据
  data: any,
  // 用于格式化 JSON 字符串的缩进空格数，默认为 2
  spaces: number = 2,
) {
  try {
    // 获取文件所在的目录路径
    const dir = dirname(filePath);
    // 递归创建文件所在的目录，如果目录已存在则不做处理
    await fs.mkdir(dir, { recursive: true });
    // 将数据转换为格式化的 JSON 字符串
    const jsonData = JSON.stringify(data, null, spaces);
    // 将 JSON 字符串写入到指定文件中，使用 UTF-8 编码
    await fs.writeFile(filePath, jsonData, 'utf8');
  } catch (error) {
    // 捕获并在控制台输出写入文件时发生的错误
    console.error('Error writing JSON file:', error);
    // 重新抛出错误，以便调用者处理
    throw error;
  }
}

/**
 * 确保指定路径的文件存在。如果文件所在的目录不存在，会递归创建这些目录；
 * 如果文件不存在，则创建一个空文件；如果文件已存在，则不做任何修改。
 *
 * @param filePath - 需要确保存在的文件的完整路径。
 * @throws 当创建目录或写入文件时发生错误，会捕获该错误，在控制台输出错误信息，并将错误重新抛出。
 */
export async function ensureFile(filePath: string) {
  try {
    // 获取文件所在的目录路径
    const dir = dirname(filePath);
    // 递归创建文件所在的目录，如果目录已存在则不会重复创建
    await fs.mkdir(dir, { recursive: true });
    // 以追加模式写入空字符串到文件中。如果文件不存在，会创建该文件；如果文件已存在，内容不会改变
    await fs.writeFile(filePath, '', { flag: 'a' });
  } catch (error) {
    // 捕获并在控制台输出确保文件存在过程中发生的错误
    console.error('Error ensuring file:', error);
    // 重新抛出错误，以便调用者可以处理该异常
    throw error;
  }
}

/**
 * 从指定文件路径读取 JSON 格式的数据并解析为 JavaScript 对象。
 *
 * @param filePath - 要读取的 JSON 文件的路径。
 * @returns 解析后的 JavaScript 对象。
 * @throws 当读取文件或解析 JSON 数据时发生错误，会在控制台输出错误信息，并将错误重新抛出。
 */
export async function readJSON(filePath: string) {
  try {
    // 以 UTF-8 编码读取指定路径的文件内容
    const data = await fs.readFile(filePath, 'utf8');
    // 将读取到的 JSON 字符串解析为 JavaScript 对象并返回
    return JSON.parse(data);
  } catch (error) {
    // 捕获并在控制台输出读取和解析 JSON 文件时发生的错误
    console.error('Error reading JSON file:', error);
    // 重新抛出错误，以便调用者处理
    throw error;
  }
}
